// 计算两个日期之间的天数
export const calculateDaysBetween = (startDate, endDate) => {
  const start = new Date(startDate)
  const end = new Date(endDate)
  const diffTime = Math.abs(end - start)
  return Math.ceil(diffTime / (1000 * 60 * 60 * 24))
}

// 计算还款日期
export const calculatePaymentDate = (startDate, period, paymentDay) => {
  const paymentDate = new Date(startDate)
  paymentDate.setMonth(paymentDate.getMonth() + period)
  paymentDate.setDate(paymentDay)
  return paymentDate
}

// 计算已还款期数
export const calculatePaidPeriods = (startDate, firstPaymentDate, totalPeriods) => {
  const start = new Date(startDate)
  const today = new Date()
  const firstPayment = new Date(firstPaymentDate)

  // 计算月份差
  const monthDiff =
    (today.getFullYear() - firstPayment.getFullYear()) * 12 +
    (today.getMonth() - firstPayment.getMonth())

  // 如果当前日期大于等于首次还款日期对应的日期，则当月也算一期
  const currentMonthPaid = today.getDate() >= firstPayment.getDate() ? 1 : 0

  // 计算已还款期数
  const paidPeriods = Math.min(monthDiff + currentMonthPaid, totalPeriods)

  return {
    paidPeriods,
    remainingPeriods: totalPeriods - paidPeriods,
    firstPaymentDate: formatDate(firstPayment)
  }
}

// 等额本息计算
export const calculateEqualPayment = (principal, rate, periods, firstPaymentDate) => {
  // 月利率
  const monthlyRate = rate / 100 / 12
  // 每月还款金额
  const monthlyPayment =
    (principal * monthlyRate * Math.pow(1 + monthlyRate, periods)) /
    (Math.pow(1 + monthlyRate, periods) - 1)
  // 总还款金额
  const totalPayment = monthlyPayment * periods
  // 总利息
  const totalInterest = totalPayment - principal

  // 生成每月还款详情
  const monthlyDetails = []
  let remainingPrincipal = principal
  const firstPayment = new Date(firstPaymentDate)

  for (let i = 0; i < periods; i++) {
    const interest = remainingPrincipal * monthlyRate
    const principal = monthlyPayment - interest
    remainingPrincipal -= principal

    // 计算当前期的还款日期
    const currentPaymentDate = new Date(firstPayment)
    currentPaymentDate.setMonth(firstPayment.getMonth() + i)

    // 格式化日期
    const formattedPaymentDate = formatDate(currentPaymentDate)

    // 判断是否已还款
    const isPaid = isPaymentCompleted(formattedPaymentDate)

    monthlyDetails.push({
      month: i + 1,
      payment: Number(monthlyPayment.toFixed(2)),
      principal: Number(principal.toFixed(2)),
      interest: Number(interest.toFixed(2)),
      remaining: Number(remainingPrincipal.toFixed(2)),
      paymentDate: formattedPaymentDate,
      isPaid: isPaid
    })
  }

  return {
    totalPayment: Number(totalPayment.toFixed(2)),
    totalInterest: Number(totalInterest.toFixed(2)),
    monthlyPayment: Number(monthlyPayment.toFixed(2)),
    monthlyDetails
  }
}

// 等额本金计算
export const calculateEqualPrincipal = (principal, rate, periods, firstPaymentDate, loanDate) => {
  // 日利率
  const dailyRate = rate / 100 / 365
  // 每月本金
  const monthlyPrincipal = principal / periods
  // 总利息
  let totalInterest = 0
  // 总还款金额
  let totalPayment = 0

  // 生成每月还款详情
  const monthlyDetails = []
  let remainingPrincipal = principal

  // 计算首月还款日期
  const start = new Date(loanDate)
  const firstPayment = new Date(firstPaymentDate)

  // 计算首月利息
  const firstMonthDays = calculateDaysBetween(start, firstPayment)
  const firstMonthInterest = principal * dailyRate * firstMonthDays
  totalInterest += firstMonthInterest

  // 格式化首次还款日期
  const formattedFirstPaymentDate = formatDate(firstPayment)

  // 判断首月是否已还款
  const isFirstMonthPaid = isPaymentCompleted(formattedFirstPaymentDate)

  // 添加首月还款详情
  monthlyDetails.push({
    month: 1,
    payment: Number((monthlyPrincipal + firstMonthInterest).toFixed(2)),
    principal: Number(monthlyPrincipal.toFixed(2)),
    interest: Number(firstMonthInterest.toFixed(2)),
    remaining: Number((remainingPrincipal - monthlyPrincipal).toFixed(2)),
    paymentDate: formattedFirstPaymentDate,
    isPaid: isFirstMonthPaid
  })

  remainingPrincipal -= monthlyPrincipal
  totalPayment += monthlyPrincipal + firstMonthInterest

  // 计算后续月份
  let currentDate = new Date(firstPayment)
  for (let i = 1; i < periods; i++) {
    const nextPaymentDate = new Date(firstPayment)
    nextPaymentDate.setMonth(firstPayment.getMonth() + i)

    // 计算本期天数
    const days = calculateDaysBetween(currentDate, nextPaymentDate)
    // 计算本期利息
    const interest = remainingPrincipal * dailyRate * days
    totalInterest += interest

    // 格式化还款日期
    const formattedPaymentDate = formatDate(nextPaymentDate)

    // 判断是否已还款
    const isPaid = isPaymentCompleted(formattedPaymentDate)

    monthlyDetails.push({
      month: i + 1,
      payment: Number((monthlyPrincipal + interest).toFixed(2)),
      principal: Number(monthlyPrincipal.toFixed(2)),
      interest: Number(interest.toFixed(2)),
      remaining: Number((remainingPrincipal - monthlyPrincipal).toFixed(2)),
      paymentDate: formattedPaymentDate,
      isPaid: isPaid
    })

    remainingPrincipal -= monthlyPrincipal
    totalPayment += monthlyPrincipal + interest
    currentDate = new Date(nextPaymentDate)
  }

  return {
    totalPayment: Number(totalPayment.toFixed(2)),
    totalInterest: Number(totalInterest.toFixed(2)),
    monthlyPayment: Number(monthlyDetails[0].payment.toFixed(2)),
    monthlyDetails
  }
}

// 固定金额计算
export const calculateFixedPayment = (
  monthlyPrincipal,
  monthlyInterest,
  totalPeriods,
  paidPeriods,
  paymentDate
) => {
  const principal = parseFloat(monthlyPrincipal)
  const interest = parseFloat(monthlyInterest)
  const total = parseInt(totalPeriods)
  const paid = parseInt(paidPeriods)
  const remaining = total - paid

  // 计算总金额
  const totalPrincipal = principal * total
  const totalInterest = interest * total
  const remainingPrincipal = principal * remaining
  const remainingInterest = interest * remaining
  const monthlyPayment = principal + interest

  // 生成还款计划
  const paymentPlan = []
  const today = new Date()
  // 设置今天的时间为 00:00:00，便于比较
  today.setHours(0, 0, 0, 0)

  for (let i = paid + 1; i <= total; i++) {
    const paymentDateObj = calculatePaymentDate(new Date(), i - paid, paymentDate)
    // 设置还款日期的时间为 23:59:59
    paymentDateObj.setHours(23, 59, 59, 999)
    const paymentDateStr = paymentDateObj.toISOString().split('T')[0]

    paymentPlan.push({
      period: i,
      principal: Number(principal.toFixed(2)),
      interest: Number(interest.toFixed(2)),
      payment: Number(monthlyPayment.toFixed(2)),
      remainingPrincipal: Number((principal * (total - i)).toFixed(2)),
      paymentDate: paymentDateStr,
      isPaid: today <= paymentDateObj // 修改为小于等于，表示当天及之前都算已还款
    })
  }

  return {
    totalPrincipal: Number(totalPrincipal.toFixed(2)),
    totalInterest: Number(totalInterest.toFixed(2)),
    remainingPrincipal: Number(remainingPrincipal.toFixed(2)),
    remainingInterest: Number(remainingInterest.toFixed(2)),
    remainingTotal: Number((remainingPrincipal + remainingInterest).toFixed(2)),
    monthlyPayment: Number(monthlyPayment.toFixed(2)),
    paymentPlan
  }
}

// 先息后本计算
export const calculateInterestFirst = (principal, rate, periods, firstPaymentDate, loanDate) => {
  // 日利率
  const dailyRate = rate / 100 / 365
  // 总利息
  let totalInterest = 0

  // 生成每月还款详情
  const monthlyDetails = []
  const today = new Date()
  // 设置今天的时间为 00:00:00，便于比较
  today.setHours(0, 0, 0, 0)

  // 计算首月还款日期
  const start = new Date(loanDate)
  const firstPayment = new Date(firstPaymentDate)

  // 计算最后一期还款日期（到期日）
  const lastPaymentDate = new Date(start)
  lastPaymentDate.setMonth(lastPaymentDate.getMonth() + periods)

  // 生成前12期还款计划
  let currentDate = new Date(start)
  for (let i = 0; i < periods; i++) {
    const nextPaymentDate = new Date(firstPayment)
    nextPaymentDate.setMonth(nextPaymentDate.getMonth() + i)
    // 设置还款日期的时间为 23:59:59
    nextPaymentDate.setHours(23, 59, 59, 999)

    // 计算本期天数
    const days = calculateDaysBetween(currentDate, nextPaymentDate)
    // 计算本期利息
    const interest = principal * dailyRate * days
    totalInterest += interest

    monthlyDetails.push({
      month: i + 1,
      payment: Number(interest.toFixed(2)),
      principal: 0,
      interest: Number(interest.toFixed(2)),
      remaining: Number(principal.toFixed(2)),
      paymentDate: formatDate(nextPaymentDate),
      isPaid: today <= nextPaymentDate, // 修改为小于等于，表示当天及之前都算已还款
      type: 'interest' // 标记为利息期
    })

    // 更新当前日期为本次还款日期
    currentDate = new Date(nextPaymentDate)
  }

  // 计算最后一期利息
  const lastInterestDays = calculateDaysBetween(
    new Date(lastPaymentDate.getFullYear(), lastPaymentDate.getMonth(), firstPayment.getDate()),
    lastPaymentDate
  )
  const lastInterest = principal * dailyRate * lastInterestDays
  totalInterest += lastInterest

  // 添加最后一期还款计划（到期日还本金+最后一期利息）
  // 设置最后一期还款日期的时间为 23:59:59
  lastPaymentDate.setHours(23, 59, 59, 999)

  monthlyDetails.push({
    month: periods + 1,
    payment: Number((principal + lastInterest).toFixed(2)),
    principal: Number(principal.toFixed(2)),
    interest: Number(lastInterest.toFixed(2)),
    remaining: 0,
    paymentDate: formatDate(lastPaymentDate),
    isPaid: today <= lastPaymentDate, // 修改为小于等于，表示当天及之前都算已还款
    type: 'principal' // 标记为本金期
  })

  return {
    totalPayment: Number((principal + totalInterest).toFixed(2)),
    totalInterest: Number(totalInterest.toFixed(2)),
    monthlyPayment: Number(monthlyDetails[0].payment.toFixed(2)),
    monthlyDetails,
    totalPeriods: periods + 1, // 总期数（利息期数+1期本金）
    interestPeriods: periods, // 利息期数
    principalPeriod: periods + 1 // 本金期数
  }
}

// 获取下一个月指定日期的日期
export const getNextMonthDate = (date, day) => {
  const nextMonth = new Date(date)
  nextMonth.setMonth(nextMonth.getMonth() + 1)
  nextMonth.setDate(day)
  return nextMonth
}

// 格式化日期为 YYYY-MM-DD 格式
export const formatDate = date => {
  const d = new Date(date)
  const year = d.getFullYear()
  const month = String(d.getMonth() + 1).padStart(2, '0')
  const day = String(d.getDate()).padStart(2, '0')
  return `${year}-${month}-${day}`
}

// 判断是否已还款（还款日及之前视为已还款）
export const isPaymentCompleted = paymentDate => {
  const today = new Date()
  today.setHours(0, 0, 0, 0)

  const paymentDay = new Date(paymentDate)
  paymentDay.setHours(0, 0, 0, 0)

  // 如果还款日小于等于今天，则视为已还款
  return paymentDay <= today
}

// 计算首月利息
export const calculateFirstMonthInterest = (principal, rate, startDate, firstPaymentDate) => {
  // 计算首月还款日期
  const start = new Date(startDate)
  const firstPayment = new Date(firstPaymentDate)

  // 计算实际天数
  const days = calculateDaysBetween(start, firstPayment)

  // 计算首月利息（按天计算）
  const dailyRate = rate / 100 / 365
  const interest = principal * dailyRate * days

  return {
    interest: Number(interest.toFixed(2)),
    days,
    firstPaymentDate: formatDate(firstPayment)
  }
}

// 计算还款计划（包含首月特殊处理）
export const calculatePaymentPlan = (
  principal,
  rate,
  periods,
  startDate,
  firstPaymentDate,
  paymentType
) => {
  // 计算首月利息和还款日期
  const firstMonth = calculateFirstMonthInterest(principal, rate, startDate, firstPaymentDate)

  // 计算已还款期数
  const { paidPeriods, remainingPeriods } = calculatePaidPeriods(
    startDate,
    firstPaymentDate,
    paymentType === 'interestFirst' ? periods + 1 : periods // 先息后本需要加1期
  )

  // 根据还款方式计算后续月份
  let result
  if (paymentType === 'equalPayment') {
    result = calculateEqualPayment(principal, rate, periods, firstPaymentDate)
  } else if (paymentType === 'equalPrincipal') {
    result = calculateEqualPrincipal(principal, rate, periods, firstPaymentDate, startDate)
  } else if (paymentType === 'interestFirst') {
    result = calculateInterestFirst(principal, rate, periods, firstPaymentDate, startDate)
  } else {
    // 免息情况
    const monthlyPrincipal = principal / periods

    // 生成每月还款详情
    const monthlyDetails = []
    let remainingPrincipal = principal
    const firstPayment = new Date(firstPaymentDate)

    for (let i = 0; i < periods; i++) {
      // 计算当前期的还款日期
      const currentPaymentDate = new Date(firstPayment)
      currentPaymentDate.setMonth(firstPayment.getMonth() + i)

      remainingPrincipal -= monthlyPrincipal

      monthlyDetails.push({
        month: i + 1,
        payment: Number(monthlyPrincipal.toFixed(2)),
        principal: Number(monthlyPrincipal.toFixed(2)),
        interest: 0,
        remaining: Number(remainingPrincipal.toFixed(2)),
        paymentDate: formatDate(currentPaymentDate),
        isPaid: false
      })
    }

    result = {
      totalPayment: Number(principal.toFixed(2)),
      totalInterest: 0,
      monthlyPayment: Number(monthlyPrincipal.toFixed(2)),
      monthlyDetails
    }
  }

  // 添加已还款期数和剩余期数
  result.paidPeriods = paidPeriods
  result.remainingPeriods = remainingPeriods
  result.totalPeriods = paymentType === 'interestFirst' ? periods + 1 : periods

  return result
}
